//
//  HLRunEngine.m
//  s.
//
//  Created by fanshijian on 2022/8/23.
//  Copyright © 2022 J. All rights reserved.
//

#import "JYRunEngine.h"
#import "JYWeakProxy.h"

@implementation JYRunEngine

static inline NSDictionary *kl_methods(void){
    static NSDictionary *methods = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        methods = @{@"open_telephone"            :@"_open_telephone:handle:",                 // 拨打系统电话
                    @"open_extern_url"           :@"_open_extern_url:handle:",                // 跳转外部url
                    @"open_url"                  :@"_open_url:handle:",                       // 跳转内部url
                    @"open_htmlData"             :@"_open_htmlData:handle:",                  // 跳转htmldata
                    @"toast"                     :@"_toast:handle:",                          // 吐司提示

                    @"_show_deviceInfo"       :@"_show_deviceInfo:handle:",    // 设备信息
                    @"_show_deviceSetList"       :@"_show_deviceSetList:handle:",    //手表设置列表
                    @"_show_searchView"       :@"_show_searchView:handle:",    //手表设置列表
                    @"_show_devicelist"       :@"_show_devicelist:handle:",    //手表设置列表
                    @"_show_AlarmListView"       :@"_show_AlarmListView:handle:",    //闹钟列表
                    @"_show_StepTargetView"       :@"_show_StepTargetView:handle:",    //计步模板
                    @"_show_NotificationSetView"       :@"_show_NotificationSetView:handle:",    // 通知设置
                    @"_show_HeartRateReminderView"       :@"_show_HeartRateReminderView:handle:",    // 心率提醒  久坐提醒   抬手亮屏
                    @"_show_HomeDataListView"       :@"_show_HomeDataListView:handle:",    // 首页的步数 心率 血氧  血压 距离  热量  睡眠列表页面
                    @"_show_VibrationSetView"       :@"_show_VibrationSetView:handle:",    // 震动设置页面
                    @"_show_HoursSetView"       :@"_show_HoursSetView:handle:",    // 12/24设置页面
                    @"_show_SwitchSet"       :@"_show_SwitchSet:handle:",    // 单开关设置页面
                    @"_show_PhysiologicalPeriodView"       :@"_show_PhysiologicalPeriodView:handle:",    // 生理期设置页面
                    @"_show_DoNotDisturbView"       :@"_show_DoNotDisturbView:handle:",    // 勿扰设置页面
                    @"_show_LanguageSelectView"       :@"_show_LanguageSelectView:handle:",    // 语言设置
                    @"_show_SOSSetView"       :@"_show_SOSSetView:handle:",    // SOS设置
                    @"show_MapView"       :@"_show_MapView:handle:",    // 地图
                    @"show_PillowDeviceInfoView"       :@"_show_PillowDeviceInfoView:handle:",    // 枕头信息页面
                    @"show_PillowSetView"       :@"_show_PillowSetView:handle:",    // 枕头设置页面
                    @"show_PillowSleepDetectionView"       :@"_show_PillowSleepDetectionView:handle:",    // 睡眠检测
                 
        };
    });
    return methods;
}

#pragma mark - >>> 业务跳转 >>>

+ (void)_show_PillowSleepDetectionView:(NSDictionary *)info handle:(id)handle{
    _showBaseKindController("PillowSleepDetectionViewController", info, handle);
}
+ (void)_show_PillowSetView:(NSDictionary *)info handle:(id)handle{
    _showBaseKindController("PillowSetViewController", info, handle);
}
+ (void)_show_deviceInfo:(NSDictionary *)info handle:(id)handle{
    _showBaseKindController("DeviceInfoViewController", info, handle);
}
+ (void)_show_PillowDeviceInfoView:(NSDictionary *)info handle:(id)handle{
    _showBaseKindController("PillowDeviceInfoViewController", info, handle);
}
+ (void)_show_MapView:(NSDictionary *)info handle:(id)handle{
    _showBaseKindController("MapViewController", info, handle);
}
+ (void)_show_deviceSetList:(NSDictionary *)info handle:(id)handle{
    _showBaseKindController("DeviceSetListViewController", info, handle);
}
+ (void)_show_searchView:(NSDictionary *)info handle:(id)handle{
    _showBaseKindController("BleSearchViewController", info, handle);
}
+ (void)_show_devicelist:(NSDictionary *)info handle:(id)handle{
    _showBaseKindController("DeviceListViewController", info, handle);
}
+ (void)_show_AlarmListView:(NSDictionary *)info handle:(id)handle{
    _showBaseKindController("AlarmListViewController", info, handle);
}
+ (void)_show_StepTargetView:(NSDictionary *)info handle:(id)handle{
    _showBaseKindController("StepTargetViewController", info, handle);
}
+ (void)_show_HomeDataListView:(NSDictionary *)info handle:(id)handle{
    _showBaseKindController("HomeDataListViewController", info, handle);
}
+ (void)_show_NotificationSetView:(NSDictionary *)info handle:(id)handle{
    _showBaseKindController("MessageNotificationViewController", info, handle);
}
+ (void)_show_HeartRateReminderView:(NSDictionary *)info handle:(id)handle{
    _showBaseKindController("HeartRateReminderViewController", info, handle);
}
+ (void)_show_VibrationSetView:(NSDictionary *)info handle:(id)handle{
    _showBaseKindController("VibrationSetViewController", info, handle);
}
+ (void)_show_SOSSetView:(NSDictionary *)info handle:(id)handle{
    _showBaseKindController("SosSetViewController", info, handle);
}
+ (void)_show_HoursSetView:(NSDictionary *)info handle:(id)handle{
    _showBaseKindController("HoursSetViewController", info, handle);
}
+ (void)_show_SwitchSet:(NSDictionary *)info handle:(id)handle{
    _showBaseKindController("SwitchSetViewController", info, handle);
}
+ (void)_show_PhysiologicalPeriodView:(NSDictionary *)info handle:(id)handle{
    _showBaseKindController("PhysiologicalPeriodViewController", info, handle);
}
+ (void)_show_DoNotDisturbView:(NSDictionary *)info handle:(id)handle{
    _showBaseKindController("DoNotDisturbViewController", info, handle);
}
+ (void)_show_LanguageSelectView:(NSDictionary *)info handle:(id)handle{
    _showBaseKindController("LanguageSelectViewController", info, handle);
}

+ (void)_show_agreementview:(NSDictionary *)info handle:(id)handle{
    _presentBaseKindController("BEAgreementCtl", info, NO,handle);
}

//info字段里面kurl @"kurl":@"login" -->本地接口转化协议(internal), 转化为真实http链接
+ (void)handleCommand:(NSDictionary *)command handle:(id)handle{
    SEL sel = NSSelectorFromString(kl_methods()[command[@"app_action"]]);
    if ([self respondsToSelector:sel]) {
        ((void(*)(id,SEL,id,id))objc_msgSend)(self,sel,command[@"info"],handle);
    }
#if DEBUG
    else{
        JYLog(@"⚠️⚠️⚠️⚠️未找到方法%@ in %@⚠️⚠️⚠️⚠️",kl_methods()[command[@"app_action"]],command);
//        NSAssert(0, @"未找到方法%@",kl_methods()[command[@"app_action"]]);
    }
#endif
}
+ (void)handleCommand:(NSDictionary *)command{
    [self handleCommand:command handle:nil];
}
static inline void _showBaseKindController(char *clsName, NSDictionary *info, void(^handle)(UIViewController *obj)){
    Class cls = (id)objc_getClass(clsName);
#if DEBUG
    if (__builtin_expect(!(cls), 0)) {
        [[NSAssertionHandler currentHandler] handleFailureInFunction:[NSThread.callStackSymbols componentsJoinedByString:@"\n"] file:@(__FILE_NAME__) lineNumber:__LINE__ description:@"无法找到类%s",clsName];
    }
#endif
    UIViewController *obj = ((UIViewController *(*)(id,SEL,id))objc_msgSend)(cls,NSSelectorFromString(@"newCtl:"),info);
    BOOL animate          = YES;
    if ([info isKindOfClass:NSDictionary.class]) {
        if (info[@"hideBarOnPush"]) {obj.hidesBottomBarWhenPushed = [info[@"hideBarOnPush"] boolValue];}
        if (info[@"animate"]) {animate = [info[@"animate"] boolValue];}
    }
    SEL set = NSSelectorFromString(@"setHandle:");
    if (handle && [obj respondsToSelector:set]) {
        ((void(*)(id,SEL,id))objc_msgSend)(obj,set, handle);
    }
    showController(obj, animate, nil);
    ((void(*)(id,SEL))objc_msgSend)(obj,sel_registerName("release"));
}
static inline void _presentBaseKindController(char *clsName, NSDictionary *info, BOOL navid, void(^handle)(UIViewController *obj)){
    Class cls = (id)objc_getClass(clsName);
#if DEBUG
    if (__builtin_expect(!(cls), 0)) {
        [[NSAssertionHandler currentHandler] handleFailureInFunction:[NSThread.callStackSymbols componentsJoinedByString:@"\n"] file:@(__FILE_NAME__) lineNumber:__LINE__ description:@"无法找到类%s",clsName];
    }
#endif
    UIViewController *obj = ((UIViewController *(*)(id,SEL,id))objc_msgSend)(cls,NSSelectorFromString(@"newCtl:"),info);
    BOOL animate          = YES;
    if ([info isKindOfClass:NSDictionary.class]) {
        if (info[@"hideBarOnPush"]) {obj.hidesBottomBarWhenPushed = [info[@"hideBarOnPush"] boolValue];}
        if (info[@"animate"]) {animate = [info[@"animate"] boolValue];}
    }
    SEL set = NSSelectorFromString(@"setHandle:");
    if (handle && [obj respondsToSelector:set]) {((void(*)(id,SEL,id))objc_msgSend)(obj,set, handle);}
    if (handle)handle(obj);
    UIViewController *top = currentTopViewController();
    if ([top isKindOfClass:UINavigationController.class]) {
        showController(obj, animate, nil);
    }else{
        if (navid) {
            BENavigationController *navc = [[BENavigationController alloc] initWithRootViewController:obj];
            navc.modalPresentationStyle  = obj.modalPresentationStyle;
            if (obj.transitioningDelegate) navc.transitioningDelegate = obj.transitioningDelegate;
            [top presentViewController:navc animated:animate completion:nil];
        }else{
            [top presentViewController:obj animated:animate completion:nil];
        }
    }
    ((void(*)(id,SEL))objc_msgSend)(obj,sel_registerName("release"));
}
+ (void)_showBaseKindController:(char *)clsName info:(NSDictionary *)info handle:(id)handle
{
    UIViewController *replace = info[@"replace"];
    if (replace) {
        Class cls = (id)objc_getClass(clsName);
        BaseViewController *obj = [cls new];
        obj.metaInfo = info;
//        UIViewController *obj = ((UIViewController *(*)(id,SEL,id))objc_msgSend)(cls,NSSelectorFromString(@"newCtl:"),info);
        replaceController(replace, obj, YES, nil);
    }else {
        _showBaseKindController(clsName, info, handle);
    }
}
#pragma mark - >>> 常用方法 >>>
#pragma --mark 拨打系统电话 ----
+ (void)_open_telephone:(NSDictionary *)info handle:(id)handle{
    NSString *phone = info[@"phone"];
    NSString *telStr = [NSString stringWithFormat:@"telprompt://%@",phone];
    [[UIApplication sharedApplication] openURL:[NSURL URLWithString:telStr] options:@{UIApplicationOpenURLOptionsSourceApplicationKey : @YES} completionHandler:^(BOOL success) {
    }];
}

#pragma --mark 跳转外部url ----
+ (void)_open_extern_url:(NSDictionary *)info handle:(id)handle{
    NSString *url = info[@"url"];
    [[UIApplication sharedApplication] openURL:[NSURL URLWithString:url] options:@{UIApplicationOpenURLOptionsSourceApplicationKey : @YES} completionHandler:^(BOOL success) {
    }];
}

#pragma --mark 加载webview HLWebViewCtl ----
+ (void)_open_url:(NSDictionary *)info handle:(id)handle{
    [self _showBaseKindController:"BEWebViewController" info:info handle:handle];
}

#pragma --mark 加载html data HLAgreementCtl ----
+ (void)_open_htmlData:(NSDictionary *)info handle:(id)handle{
    [self _showBaseKindController:"BEAgreementCtl" info:info handle:handle];
}

#pragma --mark toast提示 ----
+ (void)_toast:(NSDictionary *)info handle:(id)handle{
    toast(info);
}




@end
